﻿#include "EasyHook.h"
#include <iostream>

// 基础Hook保持不变
DECLARE_HOOK(MessageBoxW, int, HWND, LPCWSTR, LPCWSTR, UINT);

int WINAPI DetourMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType)
{
    std::wcout << L"[HOOKED] " << lpText << std::endl;
    return Original(MessageBoxW)(hWnd, lpText, lpCaption, uType);
}

IMPLEMENT_HOOK(MessageBoxW, "user32.dll", "MessageBoxW");

SETUP_HOOKS()
INSTALL_HOOK_HERE(MessageBoxW)
FINISH_HOOK_SETUP()


typedef DWORD(WINAPI *GetTickCount_t)();
GetTickCount_t OriginalGetTickCount = nullptr;

DWORD WINAPI DetourGetTickCount()
{
    std::cout << "[OFFSET HOOK] GetTickCount intercepted!" << std::endl;

    // 直接调用保存的原始函数指针
    if (OriginalGetTickCount)
    {
        return OriginalGetTickCount();
    }

    // 备用方案：直接调用系统函数
    return ::GetTickCount();
}


int main()
{
    std::cout << "=== Fixed Offset Hook Demo ===" << std::endl;

    // 获取GetTickCount的偏移并Hook
    auto   &mgr       = EasyHook::HookManager::getInstance();
    LPVOID  addr      = mgr.GetFunctionAddress("kernel32.dll", "GetTickCount");
    HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");

    if (addr && hKernel32)
    {
        DWORD offset = static_cast<DWORD>(reinterpret_cast<uintptr_t>(addr) - reinterpret_cast<uintptr_t>(hKernel32));

        std::cout << "Hooking kernel32.dll+0x" << std::hex << offset << std::dec << std::endl;

        LPVOID originalFunc = nullptr;
        if (mgr.createOffsetHook("kernel32.dll", offset, reinterpret_cast<LPVOID>(DetourGetTickCount), &originalFunc))
        {
            OriginalGetTickCount = reinterpret_cast<GetTickCount_t>(originalFunc);
            std::cout << "Offset hook installed successfully!" << std::endl;
        }
        else
        {
            std::cout << "Failed to install offset hook!" << std::endl;
        }
    }

    // 测试
    std::cout << "\nTesting hooks..." << std::endl;
    MessageBoxW(nullptr, L"Test", L"Demo", MB_OK);

    std::cout << "Calling GetTickCount..." << std::endl;
    DWORD ticks = GetTickCount();
    std::cout << "GetTickCount returned: " << ticks << std::endl;

    std::cout << "Done!" << std::endl;
    return 0;
}